home *** CD-ROM | disk | FTP | other *** search
- /* ResetRelationships.m created by cfeder on Thu 15-Dec-1994 */
-
- #import "ResetRelationships.h"
- #import "ValueForKey.h"
- #import "RelationshipKeySetter.h"
-
- @implementation EODatabaseChannel (setForeignKey)
- - objectForPrimaryKey:(NSDictionary *)key entity:(EOEntity *)entity
- // returns existing object instance if there is one, or a fault otherwise
- {
- EODatabaseContext *context = [self databaseContext];
- id object = [context objectForPrimaryKey:key entity:entity];
- if (!object) {
- object = [EOFault objectFaultWithPrimaryKey:key
- entity:entity databaseChannel:self zone:[self zone]];
- }
- return object;
- }
-
- - fetchObjectDescribedByQualifier:(EOQualifier *)qualifier
- // raises if not to-one.
- {
- BOOL success, autoTransaction = NO;
- EODatabaseContext *context = [self databaseContext];
- NSZone *zone = [self zone];
- id object;
-
- if (![context transactionNestingLevel]) {
- [context beginTransaction];
- autoTransaction = YES;
- }
-
- success = [self selectObjectsDescribedByQualifier:qualifier
- fetchOrder:nil];
- object = [self fetchWithZone:zone];
- if (!success || !object || [self fetchWithZone:zone]) {
- [self cancelFetch];
- [NSException raise:NSInternalInconsistencyException format:@"%s: error fetching object", sel_getName(_cmd)];
- }
-
- if (autoTransaction) [context commitTransaction];
- return object;
- }
-
- - destinationObjectForRelationship:relationship sourceObject:sourceObject
- // look up an exising fault, or create a new one
- {
- id object;
- // EODatabase *database = [[self databaseContext] database];
-
- if ([relationship isToMany]) {
- // EOF doesn't unique faults, so we just have to construct a new one
- EOQualifier *qual = [EOQualifier qualifierForObject:sourceObject relationship:relationship];
- object = [EOFault arrayFaultWithQualifier:qual
- fetchOrder:nil databaseChannel:self zone:[self zone]];
- } else {
- // see if this is already in the uniquing table
- if ([relationship isFlattened]) {
- EOQualifier *qual = [EOQualifier qualifierForObject:sourceObject relationship:relationship];
-
- // should fetch object from channel with qualifier
- object = [self fetchObjectDescribedByQualifier:qual];
- } else {
- // for to-ones, the primary key is always the destination of the
- // relationship
- NSDictionary *pk = [relationship destinationValuesFromSourceObject:sourceObject];
- object = [self objectForPrimaryKey:pk entity:[relationship destinationEntity]];
- }
- }
- return object;
- }
-
- - (void)updateRelationshipsInObject:object forModifiedAttributes:(NSArray *)attributes
- // After the values in object corresponding to the EOAttributes
- // in the "attributes" array have been update (perhaps with
- // takeValuesFromDictionary) this method can be called to update any
- // corresponding relationship properties. So, if a foreign dept_id
- // attribute way modified in a employee object, this would attempt to
- // reset the "toDepartment" property to point at the corresponding
- // department object.
- {
- // We should apply some caching here to make this fast. I.e. map directly
- // from attribute to list of class property relationships that this participates in.
- // For now we'll just be simple and slow.
- NSMutableArray *affectedRelationships = [NSMutableArray array];
- EOModel *model = [[[[self databaseContext] database] adaptor] model];
- EOEntity *entity = [model entityForObject:object];
- NSArray *classProperties = [entity classProperties];
- NSArray *relationships = [entity relationships];
- int i,count = [relationships count];
-
- for(i=0; i<count; i++) {
- EORelationship *relationship = [relationships objectAtIndex:i];
-
- if ([classProperties indexOfObjectIdenticalTo:relationship] != NSNotFound) {
- NSArray *joins = [relationship joins];
- int j, jcount = [joins count];
-
- for (j = 0; j < jcount; j++) {
- EOJoin *join = [joins objectAtIndex:j];
- if ([attributes indexOfObjectIdenticalTo:[join sourceAttribute]] != NSNotFound) {
- [affectedRelationships addObject:relationship];
- break;
- }
- }
- }
- }
-
- // We now have a list of affected relationships that we need to retarget
- {
- count = [affectedRelationships count];
- for(i=0; i<count; i++) {
- EORelationship *relationship = [relationships objectAtIndex:i];
- id dest = [self destinationObjectForRelationship:relationship sourceObject:object];
- [object takeValue:dest forKey:[relationship name]];
- }
- }
- }
- @end
-